package com.flyfox.ffplayer;

import java.io.File;
import java.security.SecureRandom;

import javafx.application.Platform;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.Label;
import javafx.scene.control.MenuItem;
import javafx.scene.control.Slider;
import javafx.scene.control.TableRow;
import javafx.scene.control.Tooltip;
import javafx.scene.image.ImageView;
import javafx.scene.input.Dragboard;
import javafx.scene.input.MouseButton;
import javafx.scene.input.TransferMode;
import javafx.scene.media.MediaPlayer;
import javafx.scene.media.MediaPlayer.Status;
import javafx.stage.Stage;
import javafx.util.Duration;

import com.flyfox.ffplayer.control.FuncBottom;
import com.flyfox.ffplayer.control.LyricInfo;
import com.flyfox.ffplayer.control.MusicList;
import com.flyfox.ffplayer.control.TopTitle;
import com.flyfox.ffplayer.model.CacheUtils;
import com.flyfox.ffplayer.model.FFPlayer;
import com.flyfox.ffplayer.model.PlayMode;
import com.flyfox.ffplayer.util.FFPlayerUtils;
import com.flyfox.ffplayer.util.ImageUtils;
import com.flyfox.ffplayer.util.PathUtils;

/**
 * media类
 * 
 * @author flyfox
 * @date 2014年11月6日
 */
public class FFPlayerManager {

	/**
	 * 播放列表
	 */
	private static SecureRandom random = new SecureRandom();

	/**
	 * 播放测试列表
	 */
	FFPlayer model;

	// 展示信息
	FuncBottom funcBottom = new FuncBottom();
	MusicList musicList = new MusicList();
	LyricInfo lyricInfo = new LyricInfo();
	TopTitle topTitle = new TopTitle();

	Stage stage;

	public FFPlayerManager(Stage stage) {
		this.stage = stage;

		init();
	}

	public void init() {
		bindBottom();
		initList();

		// TODO 这里可以删掉 没有歌曲，就听听伤痕吧
		if (musicList.isEmpty()) {
			String tmpPath = PathUtils.RESOURCES_PATH + File.separatorChar + "伤痕.mp3";
			FFPlayer model = FFPlayerUtils.getFFPlayer(tmpPath);
			// 加入列表
			musicList.add(model);
			// TODO 如果去除，需要这样初始化
			// primaryStage.show();
		}

		// 获取播放记录
		if (!musicList.isEmpty()) {
			model = musicList.get(CacheUtils.getIndex());
			funcBottom.getPlayModelChoiceBox().setValue(CacheUtils.getPlayMode().getName());

			bindMusic();

			play();
		}

	}

	/**
	 * 列表事件初始化
	 */
	public void initList() {

		// node添加拖入文件事件
		musicList.getTable().setOnDragOver(event -> {
			Dragboard dragboard = event.getDragboard();
			if (dragboard.hasFiles()) {
				File file = dragboard.getFiles().get(0);
				// 暂时只支持mp3
				if (file.getAbsolutePath().endsWith(".mp3")) { // 用来过滤拖入类型
					event.acceptTransferModes(TransferMode.COPY);// 接受拖入文件
				}
			}
		});

		// 拖入后松开鼠标触发的事件
		musicList.getTable().setOnDragDropped(event -> {
			Dragboard dragboard = event.getDragboard();
			if (event.isAccepted()) {
				// 获取拖入的文件
				dragboard.getFiles().forEach(file -> {
					FFPlayer model = FFPlayerUtils.getFFPlayer(file.getAbsolutePath());
					musicList.add(model);
				});
			}
		});

		// 每列的事件绑定，双击事件，右键菜单
		musicList.getTable().setRowFactory(tv -> {
			return new TableRowControl();
		});

		musicList.getTable().setTableMenuButtonVisible(true);

	}

	/**
	 * 播放列表控制
	 * 
	 * @author flyfox
	 * @date 2014年11月12日
	 */
	private class TableRowControl extends TableRow<FFPlayer> {

		public TableRowControl() {
			super();

			// 初始化右键菜单
			initContextMenu();

			// 双击
			this.setOnMouseClicked(event -> {
				if (event.getButton().equals(MouseButton.PRIMARY) && event.getClickCount() == 2
						&& TableRowControl.this.getIndex() < musicList.getTable().getItems().size()) {
					stop();
					// 获取当前音乐，播放
					CacheUtils.setIndex(TableRowControl.this.getIndex());
					model = musicList.get(TableRowControl.this.getIndex());
					bindMusic();

					play();
				}
			});
		}

		// 右键菜单
		private void initContextMenu() {
			final ContextMenu contextMenu = new ContextMenu();
			// 加载中
			contextMenu.setOnShowing(e -> {
				// System.out.println("showing");
				});
			// 显示完成
			contextMenu.setOnShown(e -> {
				// System.out.println("shown");
				});

			MenuItem deleteItem = new MenuItem("删除");
			deleteItem.setOnAction(e -> {
				if (TableRowControl.this.getIndex() < musicList.getTable().getItems().size()) {
					// 如果是当前播放，播放下一首
					if (TableRowControl.this.getIndex() == CacheUtils.getIndex()) {
						playPre();
					}
					musicList.remove(TableRowControl.this.getIndex());
				}
			});

			MenuItem clearItem = new MenuItem("清空列表");
			clearItem.setOnAction(e -> {
				stop(); // 停止播放
					// 初始化时间
					funcBottom.getTimeLabel().setText("00:00/00:00");
					// 初始化名称
					funcBottom.getName().setText("FFPlayer音乐播放器");
					// 初始化并仅用时间轴
					funcBottom.getTimeSlider().setValue(0);
					funcBottom.getTimeSlider().setDisable(true);
					// 初始化播放按钮
					Label play = funcBottom.getPlay();
					Tooltip playTooltip = new Tooltip("播放");
					((ImageView) play.getGraphic()).setImage(ImageUtils.getImage("play.png"));
					play.setTooltip(playTooltip);
					// 清空数据
					musicList.clear();
					model = null;
				});

			contextMenu.getItems().addAll(deleteItem, clearItem);
			this.setContextMenu(contextMenu);
		}
	}

	/**
	 * 底部操作事件初始化
	 */
	public void bindBottom() {

		Label play = funcBottom.getPlay();
		Tooltip playTooltip = new Tooltip("播放");
		Tooltip pauseTooltip = new Tooltip("暂停");
		ImageView playIamgeView = (ImageView) play.getGraphic();

		play.setOnMouseClicked(event -> {
			if (musicList.isEmpty()) {
				return;
			}

			// 新加入数据,获取当前音乐，绑定
			if (model == null) {
				model = musicList.get(CacheUtils.getIndex());
				bindMusic();
			}

			if (getStatus() == MediaPlayer.Status.PLAYING) {
				// 暫停播放
				playIamgeView.setImage(ImageUtils.getImage("play.png"));
				play.setTooltip(playTooltip);
				pause();
			} else {
				// 播放音訊
				play();
				play.setTooltip(pauseTooltip);
				playIamgeView.setImage(ImageUtils.getImage("pause.png"));
			}
		});

		// 上一首
		funcBottom.getPre().setOnMouseClicked(event -> {
			if (musicList.isEmpty()) {
				return;
			}

			playPre();
		});

		// 下一首
		funcBottom.getNext().setOnMouseClicked(event -> {
			if (musicList.isEmpty()) {
				return;
			}

			playNext();
		});

		Slider timeSlider = funcBottom.getTimeSlider();
		// 鼠标按下，不再更新
		timeSlider.setOnMousePressed(event -> {
			timeSlider.setValueChanging(true);
		});

		// 鼠标释放，修改时间后恢复
		timeSlider.setOnMouseReleased(event -> {
			Platform.runLater(new Runnable() {
				public void run() {
					seek(Duration.seconds(timeSlider.getValue()));

					lyricInfo.loadLyric(model, timeSlider.getValue());

					timeSlider.setValueChanging(false);
				}

			});
		});

		// 播放模式缓存
		funcBottom.getPlayModelChoiceBox().valueProperty().addListener((observable, oldValue, newValue) -> {
			CacheUtils.setPlayMode(PlayMode.modeName(newValue));
		});

		// 音量进行缓存
		funcBottom.getVolumeSlider().valueProperty().addListener((ob, oldValue, newValue) -> {
			CacheUtils.setVolume(newValue.doubleValue());
		});
	}

	/**
	 * mediaplayer事件绑定
	 */
	public void bindMusic() {
		MediaPlayer mediaPlayer = model.getMediaPlayer();

		// 如果仅用，恢复
		if (funcBottom.getTimeSlider().isDisable()) {
			funcBottom.getTimeSlider().setDisable(false);
		}

		// 初始化方法
		mediaPlayer.setOnReady(() -> {
			if (isTimeUnkown()) {
				model.setTotleTime(mediaPlayer.getTotalDuration());
			}
			if (!isTimeUnkown()) {
				funcBottom.getTimeSlider().setMax(model.getTotleTime().toSeconds());
			}
			// 播放
			// mediaPlayer.setAutoPlay(true);
				stage.show();
			});

		mediaPlayer.setOnPlaying(() -> {
			funcBottom.getName().setText(musicList.get(CacheUtils.getIndex()).getTitle());

			if (isTimeUnkown()) {
				model.setTotleTime(mediaPlayer.getTotalDuration());
			}
			if (!isTimeUnkown()) {
				funcBottom.getTimeSlider().setMax(model.getTotleTime().toSeconds());
			}

			// 播放初始化
				lyricInfo.loadLyric(model, mediaPlayer.getCurrentTime().toSeconds());
			});

		mediaPlayer.setOnEndOfMedia(() -> {
			playEnd();
		});

		mediaPlayer.setOnStopped(() -> {
			// System.out.println("stop!!!!");
			});

		// 监听media播放时间，同步展示
		mediaPlayer.currentTimeProperty().addListener((observable, oldValue, newValue) -> {
			Platform.runLater(new Runnable() {
				public void run() {
					if (musicList.isEmpty()) {
						return;
					}

					// 展示歌词
					lyricInfo.loadLyric(model, newValue.toSeconds());

					funcBottom.getTimeLabel().setText(
							FFPlayerUtils.formatTime(newValue) + "/" + FFPlayerUtils.formatTime(model.getTotleTime()));
					if (!funcBottom.getTimeSlider().isDisabled() && !funcBottom.getTimeSlider().isValueChanging()) {
						funcBottom.getTimeSlider().setValue(newValue.toSeconds());
					}
				}

			});

		});

		// 音量滑块和media声音绑定
		if (CacheUtils.getVolume() >= 0) {
			mediaPlayer.setVolume(CacheUtils.getVolume());
		}
		funcBottom.getVolumeSlider().valueProperty().bindBidirectional(mediaPlayer.volumeProperty());
	}

	public void playNext() {
		stop();
		// 获取下一首，播放
		int index = CacheUtils.getIndex();
		index += 1;
		if (index >= musicList.size()) {
			index = 0;
		}
		CacheUtils.setIndex(index);
		model = musicList.get(index);
		bindMusic();

		play();
	}

	public void playPre() {
		stop();
		// 获取下一首，播放
		int index = CacheUtils.getIndex();
		index -= 1;
		if (index < 0) {
			index = musicList.size() - 1;
		}
		CacheUtils.setIndex(index);
		model = musicList.get(index);
		bindMusic();

		play();
	}

	public void stop() {
		if (model == null) {
			return;
		}
		getMediaPlayer().stop();
	}

	public void pause() {
		getMediaPlayer().pause();
	}

	public void play() {
		getMediaPlayer().play();
	}

	public void seek(Duration seconds) {
		getMediaPlayer().seek(seconds);
	}

	public Status getStatus() {
		return getMediaPlayer().getStatus();
	}

	public MediaPlayer getMediaPlayer() {
		return model.getMediaPlayer();
	}

	private boolean isTimeUnkown() {
		return model.getTotleTime().isUnknown();
	}

	/**
	 * 播放结束
	 */
	private void playEnd() {
		switch (CacheUtils.getPlayMode()) {
		case CYCLING:
			// 循环，如果是最后一首，就放第一首
			playNext();
			break;
		case ONE_CYCLING:
			// 单曲循环
			seek(Duration.ZERO);
			break;
		case ORDER:
			playOrder();
			break;
		case RANDOM:
			playRandom();
			break;
		default:
			break;
		}
	}

	private void playRandom() {
		stop();
		CacheUtils.setIndex(random.nextInt(musicList.size()));
		model = musicList.get(CacheUtils.getIndex());
		bindMusic();
		play();
	}

	private void playOrder() {
		// 如果是最后一首，就结束
		int tmpIndex = CacheUtils.getIndex() + 1;
		if (tmpIndex >= musicList.size()) {
			seek(Duration.ZERO);
			stop();
		} else {
			playNext();
		}
	}

	// ////////////////////////////////////////////////////////////

	public FuncBottom getFuncBottom() {
		return funcBottom;
	}

	public MusicList getMusicList() {
		return musicList;
	}

	public LyricInfo getLyricInfo() {
		return lyricInfo;
	}

	public TopTitle getTopTitle() {
		return topTitle;
	}

}
